package com.kede.config.shiro;

import com.kede.entity.Menu;
import com.kede.entity.Role;
import com.kede.entity.User;
import com.kede.jwt.JwtToken;
import com.kede.service.MenuService;
import com.kede.service.RoleService;
import com.kede.service.UserService;
import com.kede.util.JwtUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;

import java.util.List;


public class MyRealm extends AuthorizingRealm {


    @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;
    @Autowired
    MenuService menuService;
  /*  //获取登录用户名
    String name=(String) principals.getPrimaryPrincipal();
    //根据用户名去数据库查询用户信息
    User user = userService.getUserByName(name);
    //添加角色和权限
    SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo();

    simpleAuthenticationInfo.add
*/


    /*授权*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        //获取登录用户名 能进这里肯定是登录过后的
        String name = (String) principals.getPrimaryPrincipal();
        //根据用户名去数据库查询用户信息,tips: 禁止用数据库sql比较密码
        User user = userService.login(name);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//        simpleAuthorizationInfo.addRole("admin");
//        simpleAuthorizationInfo.addRole("user");
//        simpleAuthorizationInfo.addStringPermission("dept:edit");

        // 根据userId 查询 所有的角色，不用 user.getRoles()
        // 下面这个用 @Select 或者 xml 实现
        List<Role> roles = roleService.getListByUserId(user.getId());
        for (Role role : roles) {
            //添加角色到认证信息的对象里面去
            simpleAuthorizationInfo.addRole(role.getName());
            // 添加权限到认证信息的对象里面去 不用 role.getPermissions()
            List<Menu> permissionList = menuService.getListByRoleId(role.getId());
            for (Menu menu : permissionList) {
                simpleAuthorizationInfo.addStringPermission(menu.getPerms());
            }
        }
        return simpleAuthorizationInfo;
    }
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }
    /*认证*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String jwtToken = (String) token.getPrincipal();
        String username = JwtUtil.getUsername(jwtToken);

        //1. 根据用户名去数据库查询用户信息,tips: 禁止用数据库sql比较密码
        User user = userService.login(username);

        if (user == null) {
            throw new UnknownAccountException("用户名或密码错误!");
        }
        //数据库表里面的 md5密码
        String password = user.getPassword();

        if (!JwtUtil.verify(jwtToken, username, JwtUtil.SECRET_PREFIX + password)) {
            throw new UnknownAccountException("用户名或密码错误!");
        }
        // 调用验证方法 没有直接比较密码

        //todo 这里可以选择更多的加密方式
        //2.表单密码的加密
//        String md5Password = DigestUtils.md5DigestAsHex(formPassword.getBytes());
//        if (!password.equals(md5Password)) {
//            throw new UnknownAccountException("用户名或密码错误!");
//        }
        //Session中注入用户信息
        SecurityUtils.getSubject().getSession().setAttribute("user",user);
        //到这一步是正确的了
        return new SimpleAuthenticationInfo(username, jwtToken, getName());
        }
 /*       public static void main(String[] args) {
        String s = DigestUtils.md5DigestAsHex("123456".getBytes());
        System.out.println(s);
        }*/
    }



